# 他妈的好难

import os
import sys
import SymbolTable
import Code
import Parser


class Assembler:
    def __init__(self) -> None:
        self.symbols = SymbolTable.SymbolTable()
        self.curSymbolAddress = 16
    
    def make1(self, file):
        parser = Parser.Parser(file)
        pc = 0
        while(parser.hasMoreCommands()):
            parser.advance()
            comType = parser.getComType()
            if(comType == parser.ACOMMAND or comType == parser.CCOMMAND):
                pc += 1
            elif(comType == parser.LCOMMAND):
                self.symbols.addEntry(parser.getSymbol(), pc)
    
    def getAddress(self, x):
        if(x.isdigit()):
            return x
        if(not self.symbols.contains(x)):
            self.symbols.addEntry(x, self.curSymbolAddress)
            self.curSymbolAddress += 1
        return self.symbols.getAddress(x)
    
    def make2(self, input, output):
        parser = Parser.Parser(input)
        fout = open(output, 'w')
        code = Code.Code()
        while(parser.hasMoreCommands()):
            parser.advance()
            comType = parser.getComType()
            if(comType == parser.ACOMMAND):
                fout.write(code.makeAinst(self.getAddress(parser.getSymbol())) + '\n')
            elif(comType == parser.CCOMMAND):
                fout.write(code.makeCinst(parser.getDest(), parser.getComp(), parser.getJump()) + '\n')
        fout.close()
    
    def assemble(self, file):
        print('Absa assemble make1' + file)
        self.make1(file)
        filex = os.path.splitext(file)
        if(filex[1] == '.asm'):
            outfile = filex[0] + '.hack'
        else:
            outfile = file + '.hack'
        print('Absa assemble make2' + file + ' -> ' + outfile)
        self.make2(file, outfile)


def main():
    absa = Assembler()
    absa.assemble(sys.argv[1])

main()